package com.kgc.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kgc.api.user.FootPrintApi;
import com.kgc.api.user.LoginApi;
import com.kgc.api.user.UserInfoApi;
import com.kgc.bean.Footprint;
import com.kgc.bean.User;
import com.kgc.config.WechatAuthConfig;
import com.kgc.service.FootPrintService;
import com.kgc.service.RegisterAndLoginService;
import com.kgc.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Classname RegisterAndLoginServiceImpl
 * @Description TODO
 * @Date 2021/6/21 10:09
 * @Created by 17402
 */
@Service
@Slf4j
public class RegisterAndLoginServiceImpl implements RegisterAndLoginService {
    @Reference(timeout = 30000,retries = 0)
    private LoginApi loginApi;
    @Reference(timeout = 30000)
    private UserInfoApi userApi;
    @Autowired
    private WechatAuthConfig wechatAuthConfig;
    @Autowired
    private RedisUtils redisUtils;
    @Reference(timeout = 30000)
    private FootPrintApi footPrintApi;
    @Autowired
    private FootPrintService footPrintService;

    @Override
    public ReturnResult<Map<String, Object>> sendCode(String phone) {
        return loginApi.sendCode(phone);
    }

    @Override
    public ReturnResult<Map<String, Object>> userCode2logInOrRegistered(String phone, String code, HttpServletRequest request, HttpServletResponse resp) {
        //将cookie中的足迹存入数据库
        List<String> goodIdList=footPrintService.getGoodsIdFromCookies(request);
        log.info("------{}------",goodIdList);
        footPrintService.delGoodsIdFromCookies(request,resp);
        return loginApi.userCode2loginOrRegistered(phone,code,goodIdList);
    }

    @Override
    public ReturnResult<Map<String, Object>> getWxLoginQRCode() {
        return loginApi.getWxLoginQRCode();
    }

    @Override
    public ReturnResult<Map<String, Object>> wechatAuthorizationCallback(HttpServletRequest request, HttpServletResponse resp) {
        Map<String,Object> callBackReturnData=new HashMap<>();

        // 记录回调的code信息，从request中获取，（定义参数，回调的参数名，自动绑定）
        // 官方说明：如果用户同意授权，页面将跳转至 redirect_uri/?code=CODE&state=STATE。
        String wechatCode = request.getParameter("code");
        log.info("微信公众号异步回调code值：{}", wechatCode);
        log.info("-------accessTokenUrl:{}",wechatAuthConfig.getAccessTokenUri());

        // 验证一下code的有效性
        if (StringUtils.isEmpty(wechatCode)) {
            log.error("微信异步回调code异常，为空！");
            callBackReturnData.put("msg","微信异步回调code异常，为空！");
            return ResultBuildUtil.success(callBackReturnData);
        }

        // 通过code换取网页授权access_token
        // ?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
        StringBuffer accessTokenUrl = new StringBuffer(wechatAuthConfig.getAccessTokenUri());
        accessTokenUrl.append("?appid=").append(wechatAuthConfig.getAppId())
                .append("&secret=").append(wechatAuthConfig.getAppSecret())
                .append("&code=").append(wechatCode)
                .append("&grant_type=authorization_code");
        log.info("access 地址：{}", accessTokenUrl.toString());

        // 获取token，包括获取用户信息服务器否发起，通过程序发送请求
        // 没有异步回调，要同步处理，返回json，处理json
        String resultInfo = HttpClient4Util.getResponse4GetAsString(accessTokenUrl.toString(), "utf-8");
        // 解析返回结果
        JSONObject resultObj = JSON.parseObject(resultInfo);
        String access_token = resultObj.getString("access_token");
        String openid = resultObj.getString("openid");
        log.info("通过code换取网页授予的token:{},openid:{}", access_token,openid);
        // 拉取用户信息(需scope为 snsapi_userinfo)
        //http：GET（请使用https协议） https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
        // 根据获取的access_token 和openid 请求用户基本信息
        StringBuffer pullUserInfoUrl = new StringBuffer(wechatAuthConfig.getUserinfoUri());
        pullUserInfoUrl.append("?access_token=").append(access_token)
                .append("&openid=").append(openid)
                .append("&lang=zh_CN");
        //请求拉请信息
        String resultUserInfo = HttpClient4Util.getResponse4GetAsString(pullUserInfoUrl.toString(), "utf-8");

        JSONObject userJson = JSONObject.parseObject(resultUserInfo);
        log.info("拉取到的微信授权的信息：{}",userJson);
        User user=JSONObject.parseObject(resultUserInfo,User.class);
        String token= UUID.randomUUID().toString();
        String msg;

        if(userApi.doesOpenidExist(openid)){
            //openid 存在 直接登录 将数据库中的用户信息存入redis
            User userFromTable=userApi.findUserBasedOnOpenID(openid);
            user=userFromTable;
            Date date=new Date();
            if(user.getVipEndTime()==null||user.getVipEndTime().before(date)){
                user.setIsvip(0);
                userApi.modifyUserInformation(user);
            }
            redisUtils.set(token,JSON.toJSONString(userFromTable),24*60*60*3);
            msg="登录成功";
            log.info("登录成功。");

        }else {
            //openid 不存在 注册 将此次授权信息存入redis 并存入用户表,强迫绑定手机号
            user.setIsvip(0);
            userApi.addUser(user);
            Integer userId=userApi.findUserBasedOnOpenID(user.getOpenid()).getUserId();
            user.setUserId(userId);
            //去绑定手机号
            redisUtils.set(token,JSON.toJSONString(user),24*60*60*3);
            msg="请绑定手机号";
            log.info("微信注册成功，请绑定手机号。");



        }
        //将cookie中的足迹存入数据库
        List<String> goodIdList=footPrintService.getGoodsIdFromCookies(request);
        User finalUser = user;
        Collections.reverse(goodIdList);
        if (null != goodIdList && goodIdList.size() > 0) {

            goodIdList.forEach(goodId->{
                if(footPrintApi.findFootprint(goodId,finalUser.getUserId())==null){
                    //
                    Footprint footprint=new Footprint();
                    footprint.setUserId(finalUser.getUserId());
                    footprint.setFootprintGoodsId(goodId);
                    footprint.setFootprintTime(new Date());
                    footPrintApi.addFootPrint(footprint);
                }else {
                    //
                    Footprint footprint=footPrintApi.findFootprint(goodId,finalUser.getUserId());
                    footprint.setFootprintTime(new Date());
                    footPrintApi.updateFootTime(footprint);
                }

            });
        }

        footPrintService.delGoodsIdFromCookies(request,resp);
        callBackReturnData.put("wechatCode",wechatCode);
        callBackReturnData.put("userJson",userJson);
        callBackReturnData.put("token",token);
        callBackReturnData.put("msg",msg);
        return ResultBuildUtil.success(callBackReturnData);
    }

    @Override
    public ReturnResult<Map<String, Object>> editPersonalInformation(String username, String password, String nickname, String sex, String phone, String country, String province, User user, String token) {
        Map<String, Object> ReturnData = new HashMap<>();
        //        ************username唯一，不允许重复，相当于账号*************
        if (!StringUtils.isEmpty(username) && !userApi.doesTheUsernameExist(username)) {
            user.setUsername(username);
        } else if (!StringUtils.isEmpty(username) && userApi.doesTheUsernameExist(username)) {
            return ResultBuildUtil.fail("1005", "用户名已存在");
        }

        if (!StringUtils.isEmpty(password)) {
            user.setPassword(MD5Until.getMD5(password));
        }
        if (!StringUtils.isEmpty(nickname)) {
            user.setNickname(nickname);
        }
        if (!StringUtils.isEmpty(sex)) {
            user.setSex(Integer.valueOf(sex));
        }
        if (!StringUtils.isEmpty(phone) && !userApi.doesTheUsernameExist(phone)) {
            user.setPhone(phone);
        } else if (!StringUtils.isEmpty(phone) && userApi.selectUserByPhone(phone) != null) {
            //微信注册后绑定吧手机号，首先需要判断手机是否存在，存在则将原有信息移入微信账号，将原有记录删除
            User oldUser=userApi.selectUserByPhone(phone);
            log.info("-----------------oldUser:{}",oldUser.toString());
            if(user.getUserId()!=null){
                user.setCreatetime(oldUser.getCreatetime());
                user.setIntegral(oldUser.getIntegral());
                user.setPassword(oldUser.getPassword());
                user.setSignDays(oldUser.getSignDays());
                user.setPhone(oldUser.getPhone());
                user.setSignLastTime(oldUser.getSignLastTime());
                if(oldUser.getIsvip()==1)
                {
                    user.setIsvip(oldUser.getIsvip());
                    user.setVipBeginTime(oldUser.getVipBeginTime());
                    user.setVipEndTime(oldUser.getVipEndTime());

                }
                userApi.delUserById(userApi.selectUserByPhone(phone).getUserId());
            }else {
                return ResultBuildUtil.fail("1006", "手机号已存在");
            }
        }
        if (!StringUtils.isEmpty(country)) {
            user.setCountry(country);
        }
        if (!StringUtils.isEmpty(province)) {
            user.setProvince(province);
        }

        log.info("修改后的user:{}", user.toString());
        if (userApi.modifyUserInformation(user)) {
            ReturnData.put("msg", "修改成功");
            //存redis
            redisUtils.set(token, JSON.toJSONString(user), 24 * 60 * 60 * 3);
            //修改数据库用户

        } else {
            ReturnData.put("msg", "修改失败");
        }
        return ResultBuildUtil.success(ReturnData);
    }


}
